#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json
import requests
import argparse
import sys
from datetime import datetime
from typing import List, Dict, Optional


class ApiDocQueryTool:
    def __init__(self, config_file: str = "api-doc-config.json"):
        """初始化API文档查询工具"""
        try:
            with open(config_file, 'r', encoding='utf-8') as f:
                self.config = json.load(f)
        except FileNotFoundError:
            print(f"错误: 配置文件 {config_file} 不存在")
            sys.exit(1)
        except json.JSONDecodeError:
            print(f"错误: 配置文件 {config_file} 格式错误")
            sys.exit(1)

        self.base_url = self.config.get('baseUrl', '')
        self.token = self.config.get('token', '')
        self.endpoints = self.config.get('endpoints', {})

        if not self.base_url or not self.token:
            print("错误: 配置文件中缺少baseUrl或token")
            sys.exit(1)

    def search_api(self, service_name: str, api_path: str, cmdb_uid_list: List[str] = None) -> List[Dict]:
        """搜索API接口"""
        url = f"{self.base_url}{self.endpoints['search']}"

        headers = {
            'Content-Type': 'application/json',
            'x-lt-token': self.token
        }

        payload = {
            "cmdbUidList": cmdb_uid_list or [],
            "likeQuery": True,
            "pageNo": 1,
            "pageSize": 100,
            "searchText": api_path
        }

        try:
            response = requests.post(url, headers=headers, json=payload)
            response.raise_for_status()

            result = response.json()
            if result.get('code') != '0':
                print(f"搜索失败: {result.get('msg', '未知错误')}")
                return []

            return result.get('info', {}).get('data', [])

        except requests.RequestException as e:
            print(f"请求失败: {e}")
            return []

    def find_best_match(self, api_results: List[Dict], service_name: str, api_path: str) -> Optional[Dict]:
        """找到最匹配的API记录"""
        if not api_results:
            return None

        # 过滤匹配的记录
        matches = []
        for api in api_results:
            # 检查路径匹配
            if api_path.lower() in api.get('path', '').lower():
                # 检查服务名匹配（如果提供了服务名）
                if service_name:
                    cmdb_name = api.get('cmdbName', '').lower()
                    if service_name.lower() in cmdb_name:
                        matches.append(api)
                else:
                    matches.append(api)

        if not matches:
            matches = api_results

        # 按更新时间排序，选择最新的
        matches.sort(key=lambda x: x.get('lastUpdateTime', ''), reverse=True)
        return matches[0]

    def get_api_detail(self, uid: str, cmdb_uid: str, version: str = None) -> Optional[Dict]:
        """获取API详细信息"""
        url = f"{self.base_url}{self.endpoints['detail']}"

        headers = {
            'Content-Type': 'application/json',
            'x-lt-token': self.token
        }

        params = {
            'uid': uid,
            'cmdbUid': cmdb_uid
        }

        if version:
            params['version'] = version

        try:
            response = requests.get(url, headers=headers, params=params)
            response.raise_for_status()

            result = response.json()
            if result.get('code') != '0':
                print(f"获取详情失败: {result.get('msg', '未知错误')}")
                return None

            return result.get('info', {})

        except requests.RequestException as e:
            print(f"请求失败: {e}")
            return None

    def display_api_doc(self, api_info: Dict, api_detail: Dict):
        """展示API文档"""
        print("=" * 80)
        print("API 接口文档")
        print("=" * 80)

        # 基本信息
        print(f"接口名称: {api_info.get('title', 'N/A')}")
        print(f"接口路径: {api_info.get('path', 'N/A')}")
        print(f"请求方法: {api_info.get('method', 'N/A')}")
        print(f"所属应用: {api_info.get('cmdbName', 'N/A')}")
        print(f"维护人: {api_info.get('maintainer', 'N/A')}")
        print(f"最后更新: {api_info.get('lastUpdateTime', 'N/A')}")
        print(f"接口状态: {self._get_status_text(api_detail.get('status', 0))}")
        print()

        # 接口详情
        content = api_detail.get('content', {})
        if content and content.get('content'):
            print("接口详细信息:")
            print("-" * 40)
            try:
                # 尝试解析JSON格式的内容
                content_data = json.loads(content['content'])
                print(json.dumps(content_data, indent=2, ensure_ascii=False))
            except json.JSONDecodeError:
                # 如果不是JSON格式，直接输出
                print(content['content'])
            print()

        print(f"版本信息: {content.get('version', 'N/A')}")
        print(f"内容哈希: {content.get('contentHash', 'N/A')}")
        print("=" * 80)

    def _get_status_text(self, status: int) -> str:
        """获取状态文本"""
        status_map = {
            1: "已完成",
            2: "未完成",
            3: "已发布",
            4: "不可靠",
            5: "数据缺失",
            6: "数据错误"
        }
        return status_map.get(status, "未知状态")

    def query(self, service_name: str, api_path: str, cmdb_uid_list: List[str] = None):
        """执行查询流程"""
        print(f"正在搜索API: {api_path}")
        if service_name:
            print(f"服务名: {service_name}")

        # 1. 搜索API
        api_results = self.search_api(service_name, api_path, cmdb_uid_list)

        if not api_results:
            print("未找到匹配的API接口")
            return

        print(f"找到 {len(api_results)} 个相关接口")

        # 2. 找到最匹配的记录
        best_match = self.find_best_match(api_results, service_name, api_path)

        if not best_match:
            print("未找到匹配的API接口")
            return

        print(f"选择最匹配的接口: {best_match.get('title', best_match.get('path'))}")

        # 3. 获取详细信息
        uid = best_match.get('uid')
        cmdb_uid = best_match.get('cmdbUid')

        if not uid or not cmdb_uid:
            print("错误: 无法获取接口的uid或cmdbUid")
            return

        api_detail = self.get_api_detail(uid, cmdb_uid)

        if not api_detail:
            print("无法获取接口详细信息")
            return

        # 4. 展示文档
        self.display_api_doc(best_match, api_detail)


def main():
    parser = argparse.ArgumentParser(description='API文档查询工具')
    parser.add_argument('service_name', help='服务名称')
    parser.add_argument('api_path', help='接口路径')
    parser.add_argument('--config', '-c', default='api-doc-config.json', help='配置文件路径')
    parser.add_argument('--cmdb-uid', action='append', help='CMDB应用UID列表（可多次使用）')

    args = parser.parse_args()

    tool = ApiDocQueryTool(args.config)
    tool.query(args.service_name, args.api_path, args.cmdb_uid)


if __name__ == '__main__':
    main()
